package org.xmonkey.controller.extractor.visitors;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.xmonkey.Messages;

/**
 * This class represents a visitor that visits *.java resources
 * It is responsible for handling them as ICompilationUnit elements and delegate their visits
 * @author jacopom
 *
 */
public final class ResourceVisitor implements IResourceVisitor {
	private IProgressMonitor monitor;
	private IProject project;
	private ASTParser parser;

	public ResourceVisitor(IProgressMonitor monitor, IProject project) {
		this.monitor = monitor;
		this.project = project;
		this.parser = ASTParser.newParser(AST.JLS4);
		parser.setKind(ASTParser.K_COMPILATION_UNIT);
	}

	public boolean visit(IResource resource) {
		if(resource.getType() == IResource.FILE){
			fileHandler((IFile) resource);
			return false; // stop analyzing that branch of the tree
		}
		// else this branch contains a project or folder, keep walking it
		return true;
	}
	
	private void fileHandler(IFile file) {
		String fileExtension = file.getFileExtension();
		if (fileExtension != null && fileExtension.equalsIgnoreCase("java")) { //$NON-NLS-1$
			IJavaElement element = JavaCore.create(file);
			ICompilationUnit compilationUnit = (ICompilationUnit) element;
			// handle each type in the compilation unit
			parseCompilationUnit(compilationUnit);
		}
	}
	
	private void parseCompilationUnit(ICompilationUnit unit) {
		if(!monitor.isCanceled()){
			monitor.setTaskName(Messages.ResourceVisitor_1 + unit.getElementName());
			parser.setSource(unit);
			parser.setResolveBindings(true);
			CompilationUnit cu = (CompilationUnit) parser.createAST(null);
			cu.accept(new CompilationUnitVisitor(project, true));
			monitor.worked(1);
		}
	}
}
